﻿using System;
using System.Collections.Generic;
using System.Linq;
using Caliburn.Micro;
using NHibernate;
using TimeKeeper.Entities;
using TimeKeeper.Events;
using TimeKeeper.Infrastructure;

namespace TimeKeeper.ViewModels
{
    public class ShellViewModel : Conductor<IScreen>.Collection.OneActive, IHandle<ProjectChanged>
    {
        public override string DisplayName { get { return "Time Keeper"; } set { } }

        public IDictionary<int, string> Projects { get; private set; }

        private KeyValuePair<int, string> _selectedProject;
        public KeyValuePair<int, string> SelectedProject
        {
            get { return _selectedProject; }
            set
            {
                if (_selectedProject.Equals(value)) return;
                _selectedProject = value;
                NotifyOfPropertyChange(() => SelectedProject);
                _eventAggregator.Publish(value.Key == 0 ? new ActualProjectChanged(null) : new ActualProjectChanged(value.Key));
            }
        }

        private readonly IEventAggregator _eventAggregator;
        private readonly IStatelessSession _session;
        private readonly IViewModelFactory<ProjectEditViewModel> _projectEditViewModelViewModelFactory;

        public ShellViewModel(IEventAggregator eventAggregator, IEnumerable<ITab> tabs, IStatelessSession session, IViewModelFactory<ProjectEditViewModel> projectEditViewModelViewModelFactory)
        {
            _session = session;
            _projectEditViewModelViewModelFactory = projectEditViewModelViewModelFactory;
            _eventAggregator = eventAggregator;

            Items.AddRange(tabs);

            LoadProjects();
            SelectedProject = Projects.FirstOrDefault();
        }

        private void LoadProjects()
        {
            Projects = new Dictionary<int, string>();
            _session.QueryInTransaction<Project>(p => Projects = p.OrderBy(x => x.Name).ToDictionary(x => x.Id, x => x.Name));
            NotifyOfPropertyChange(() => Projects);
        }

        public IResult New()
        {
            return _projectEditViewModelViewModelFactory.AsDialogResult();
        }

        public void Handle(ProjectChanged message)
        {
            var selected = SelectedProject.Key;

            if (message.Type == ChangeType.Added) selected = message.Id;
            
            LoadProjects();
            
            try
            {
                SelectedProject = Projects.First(x => x.Key == selected);
            }
            catch (InvalidOperationException)
            {
                SelectedProject = Projects.FirstOrDefault();
            }
        }
    }
}
